using System;
using System.Collections.Generic;
using System.ComponentModel;
using Microsoft.Ccr.Core;
using Microsoft.Dss.Core.Attributes;
using Microsoft.Dss.ServiceModel.Dssp;
using Microsoft.Dss.ServiceModel.DsspServiceBase;
using W3C.Soap;
using Emgu.Util;
using Emgu.CV.Structure;
using Emgu.CV.UI;
using Robotics.ImgHoughLines;
using System.Drawing;

namespace Robotics.ImgHoughLines
{
    /// <summary>
    /// ImgHoughLines contract class
    /// </summary>
    public sealed class Contract
    {
        /// <summary>
        /// DSS contract identifer for ImgHoughLines
        /// </summary>
        [DataMember]
        public const string Identifier = "http://schemas.tempuri.org/2010/08/imghoughlines.html";
    }

    /// <summary>
    /// ImgHoughLines state
    /// </summary>
    [DataContract]
    public class ImgHoughLinesState
    {
        /// <summary>
        /// Canny Threshold to find intital segments of strong edges.
        /// </summary>
        [DataMember]
        [Description("Canny Threshold to find intital segments of strong edges")]
        public Gray CannyThreshold;

        /// <summary>
        /// Canny Threshold for edge linking.
        /// </summary>
        [DataMember]
        [Description("Canny Threshold for edge linking")]
        public Gray CannyThresholdLinking;

        /// <summary>
        /// Distance Resolution in pixels.
        /// </summary>
        [DataMember]
        [Description("Distance Resolution in pixels")]
        public double RhoResolution;

        /// <summary>
        /// Angle Resolution in radians.
        /// </summary>
        [DataMember]
        [Description("Angle Resolution in radians")]
        public double ThetaResolution;
        
        /// <summary>
        /// Threshold for lines.
        /// </summary>
        [DataMember]
        [Description("Threshold for lines")]
        public int Threshold;
        
        /// <summary>
        /// Min width of line.
        /// </summary>
        [DataMember]
        [Description("Min width of line")]
        public double MinLineWidth;
        
        /// <summary>
        /// Min gap between lines.
        /// </summary>
        [DataMember]
        [Description("Min gap between lines")]
        public double GapBetweenLines;
    }

    /// <summary>
    /// ImgHoughLines main operations port
    /// </summary>
    [ServicePort]
    public class ImgHoughLinesOperations : PortSet<DsspDefaultLookup, DsspDefaultDrop, Get, Subscribe, HoughLinesImage, NotifyImageHoughLines>
    {
    }

    /// <summary>
    /// ImgHoughLines get operation
    /// </summary>
    public class Get : Get<GetRequestType, PortSet<ImgHoughLinesState, Fault>>
    {
        /// <summary>
        /// Creates a new instance of Get
        /// </summary>
        public Get()
        {
        }

        /// <summary>
        /// Creates a new instance of Get
        /// </summary>
        /// <param name="body">the request message body</param>
        public Get(GetRequestType body)
            : base(body)
        {
        }

        /// <summary>
        /// Creates a new instance of Get
        /// </summary>
        /// <param name="body">the request message body</param>
        /// <param name="responsePort">the response port for the request</param>
        public Get(GetRequestType body, PortSet<ImgHoughLinesState, Fault> responsePort)
            : base(body, responsePort)
        {
        }
    }

    /// <summary>
    /// Image HoughLines Operation
    /// </summary>
    public class HoughLinesImage : Update<HoughLinesImageRequest, PortSet<DefaultUpdateResponseType, Fault>>
    {
        public HoughLinesImage()
        {
        }

        /// <summary>
        /// Constructor with HoughLinesImageRequest
        /// </summary>
        public HoughLinesImage(HoughLinesImageRequest body)
            : base(body)
        {
        }
    }

    /// <summary>
    /// HoughLines Image Request Type
    /// </summary>
    [DataContract]
    [DataMemberConstructor]
    public class HoughLinesImageRequest
    {
        [DataMember, DataMemberConstructor]
        [Description("Data for Input Image")]
        public byte[,,] ImageForHoughLines;

        /// <summary>
        /// Constructor
        /// </summary>
        public HoughLinesImageRequest()
        {
        }
        /// <summary>
        /// Constructor with Image Data Request (byte[,,])
        /// </summary>
        public HoughLinesImageRequest(byte[, ,] request)
        {
            ImageForHoughLines = request;
        }
    }

    /// <summary>
    /// Image HoughLines Notification Operation
    /// </summary>
    [DisplayName("ImageHoughLines done.")]
    [Description("Indicates that image HoughLines is done.")]
    public class NotifyImageHoughLines : Update<HoughLinesResult, PortSet<DefaultUpdateResponseType, Fault>>
    {
        /// <summary>
        /// Constructor
        /// </summary>
        public NotifyImageHoughLines()
        {
        }

        /// <summary>
        /// Constructor with HoughLinesResult
        /// </summary>
        public NotifyImageHoughLines(HoughLinesResult body)
            : base(body)
        {
        }
    }

    /// <summary>
    /// Image HoughLines Result
    /// </summary>
    [DataContract]
    public class HoughLinesResult
    {
        /// <summary>
        /// HoughLines Result
        /// </summary>
        [DataMember]
        [Description("The resulting HoughLines")]
        public LineSegment2D[] HoughLinesRes;

        /// <summary>
        /// Constructor
        /// </summary>
        public HoughLinesResult()
        {
        }
        /// <summary>
        /// Constructor with HoughLines Result (LineSegment2D[])
        /// </summary>
        public HoughLinesResult(LineSegment2D[] result)
        {
            HoughLinesRes = result;
        }
    }

    /// <summary>
    /// ImgHoughLines subscribe operation
    /// </summary>
    public class Subscribe : Subscribe<SubscribeRequestType, PortSet<SubscribeResponseType, Fault>>
    {
        /// <summary>
        /// Creates a new instance of Subscribe
        /// </summary>
        public Subscribe()
        {
        }

        /// <summary>
        /// Creates a new instance of Subscribe
        /// </summary>
        /// <param name="body">the request message body</param>
        public Subscribe(SubscribeRequestType body)
            : base(body)
        {
        }

        /// <summary>
        /// Creates a new instance of Subscribe
        /// </summary>
        /// <param name="body">the request message body</param>
        /// <param name="responsePort">the response port for the request</param>
        public Subscribe(SubscribeRequestType body, PortSet<SubscribeResponseType, Fault> responsePort)
            : base(body, responsePort)
        {
        }
    }
}


